package com.blog.cmrpersonalblog.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.blog.cmrpersonalblog.common.Result;
import com.blog.cmrpersonalblog.dto.role.requset.RoleCreateRequest;
import com.blog.cmrpersonalblog.dto.role.requset.RoleQueryRequest;
import com.blog.cmrpersonalblog.dto.role.requset.RoleResponse;
import com.blog.cmrpersonalblog.dto.role.requset.RoleUpdateRequest;
import com.blog.cmrpersonalblog.entity.SysPermission;
import com.blog.cmrpersonalblog.service.SysPermissionService;
import com.blog.cmrpersonalblog.service.SysRoleService;
import com.blog.cmrpersonalblog.service.SysUserRoleService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 角色管理控制器
 * 只有管理员可以操作
 */
@Slf4j
@RestController
@RequestMapping("/admin/roles")
@CrossOrigin(origins = "*", maxAge = 3600)
@SaCheckRole("admin")
public class RoleManagementController {

   @Resource
    private SysRoleService sysRoleService;

   @Resource
    private SysPermissionService sysPermissionService;

   @Resource
    private SysUserRoleService sysUserRoleService;

    /**
     * 分页查询角色列表
     */
    @GetMapping("/list")
    public Result<IPage<RoleResponse>> getRoleList(RoleQueryRequest queryRequest) {
        log.info("管理员查询角色列表: {}", queryRequest);
        try {
            IPage<RoleResponse> pageResult = sysRoleService.getRoleList(queryRequest);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("查询角色列表失败", e);
            return Result.error("查询角色列表失败：" + e.getMessage());
        }
    }

    /**
     * 获取角色详情
     */
    @GetMapping("/{roleId}/detail")
    public Result<RoleResponse> getRoleDetail(@PathVariable @NotNull Long roleId) {
        log.info("管理员查询角色详情: roleId={}", roleId);
        try {
            RoleResponse role = sysRoleService.getRoleDetail(roleId);
            if (role == null) {
                return Result.error("角色不存在");
            }
            return Result.success(role);
        } catch (Exception e) {
            log.error("查询角色详情失败", e);
            return Result.error("查询角色详情失败：" + e.getMessage());
        }
    }

    /**
     * 创建角色
     */
    @PostMapping("/createRole")
    public Result<Void> createRole(@RequestBody @Valid RoleCreateRequest createRequest) {
        log.info("管理员创建角色: {}", createRequest);
        try {
            createRequest.setCreateBy(StpUtil.getLoginIdAsString());
            boolean success = sysRoleService.createRole(createRequest);
            if (success) {
                return Result.success("角色创建成功");
            } else {
                return Result.error("角色创建失败");
            }
        } catch (Exception e) {
            log.error("创建角色失败", e);
            return Result.error("创建角色失败：" + e.getMessage());
        }
    }

    /**
     * 更新角色
     */
    @PutMapping("/{roleId}/update")
    public Result<Void> updateRole(@PathVariable @NotNull Long roleId,
                                   @RequestBody @Valid RoleUpdateRequest updateRequest) {
        log.info("管理员更新角色: roleId={}, request={}", roleId, updateRequest);
        try {
            // 获取当前登录用户的角色
            Long currentUserId = StpUtil.getLoginIdAsLong();
            List<Long> currentUserRoleIds = sysUserRoleService.getRoleIdsByUserId(currentUserId);
            
            // 检查是否尝试修改自己拥有的角色
            if (currentUserRoleIds.contains(roleId)) {
                return Result.error("管理员不能修改自己拥有的角色");
            }
            
            updateRequest.setRoleId(roleId);
            updateRequest.setUpdateBy(StpUtil.getLoginIdAsString());
            
            boolean success = sysRoleService.updateRole(updateRequest);
            if (success) {
                return Result.success("角色更新成功");
            } else {
                return Result.error("角色更新失败");
            }
        } catch (Exception e) {
            log.error("更新角色失败", e);
            return Result.error("更新角色失败：" + e.getMessage());
        }
    }

    /**
     * 删除角色
     */
    @DeleteMapping("/{roleId}/delete")
    public Result<Void> deleteRole(@PathVariable @NotNull Long roleId) {
        log.info("管理员删除角色: roleId={}", roleId);
        try {
            // 获取当前登录用户的角色
            Long currentUserId = StpUtil.getLoginIdAsLong();
            List<Long> currentUserRoleIds = sysUserRoleService.getRoleIdsByUserId(currentUserId);
            
            // 检查是否尝试删除自己拥有的角色
            if (currentUserRoleIds.contains(roleId)) {
                return Result.error("管理员不能删除自己拥有的角色");
            }
            
            boolean success = sysRoleService.deleteRole(roleId);
            if (success) {
                return Result.success("角色删除成功");
            } else {
                return Result.error("角色删除失败");
            }
        } catch (Exception e) {
            log.error("删除角色失败", e);
            return Result.error("删除角色失败：" + e.getMessage());
        }
    }

    /**
     * 批量删除角色
     */
    @DeleteMapping("/batchDelete")
    public Result<Void> deleteRoles(@RequestBody @NotEmpty List<Long> roleIds) {
        log.info("管理员批量删除角色: roleIds={}", roleIds);
        try {
            // 获取当前登录用户的角色
            Long currentUserId = StpUtil.getLoginIdAsLong();
            List<Long> currentUserRoleIds = sysUserRoleService.getRoleIdsByUserId(currentUserId);
            
            // 检查是否尝试删除自己拥有的角色
            for (Long roleId : roleIds) {
                if (currentUserRoleIds.contains(roleId)) {
                    return Result.error("管理员不能删除自己拥有的角色");
                }
            }
            
            boolean success = sysRoleService.deleteRoles(roleIds);
            if (success) {
                return Result.success("角色批量删除成功");
            } else {
                return Result.error("角色批量删除失败");
            }
        } catch (Exception e) {
            log.error("批量删除角色失败", e);
            return Result.error("批量删除角色失败：" + e.getMessage());
        }
    }

    /**
     * 更新角色状态
     */
    @PutMapping("/{roleId}/updateStatus")
    public Result<Void> updateRoleStatus(@PathVariable @NotNull Long roleId,
                                         @RequestParam @NotNull String status) {
        log.info("管理员更新角色状态: roleId={}, status={}", roleId, status);
        try {
            // 获取当前登录用户的角色
            Long currentUserId = StpUtil.getLoginIdAsLong();
            List<Long> currentUserRoleIds = sysUserRoleService.getRoleIdsByUserId(currentUserId);
            
            // 检查是否尝试修改自己拥有的角色状态
            if (currentUserRoleIds.contains(roleId)) {
                return Result.error("管理员不能修改自己拥有的角色状态");
            }
            
            String currentUserName = StpUtil.getLoginIdAsString();
            boolean success = sysRoleService.updateRoleStatus(roleId, status, currentUserName);
            if (success) {
                String statusText = "0".equals(status) ? "启用" : "停用";
                return Result.success("角色" + statusText + "成功");
            } else {
                return Result.error("角色状态更新失败");
            }
        } catch (Exception e) {
            log.error("更新角色状态失败", e);
            return Result.error("更新角色状态失败：" + e.getMessage());
        }
    }

    /**
     * 检查角色标识是否存在
     */
    @GetMapping("/checkRoleKey")
    public Result<Boolean> checkRoleKey(@RequestParam String roleKey,
                                        @RequestParam(required = false) Long excludeId) {
        try {
            boolean exists = sysRoleService.existsRoleKey(roleKey, excludeId);
            return Result.success(!exists); // 返回是否可用（不存在则可用）
        } catch (Exception e) {
            log.error("检查角色标识失败", e);
            return Result.error("检查角色标识失败：" + e.getMessage());
        }
    }

    /**
     * 获取所有角色（用于下拉选择）
     */
    @GetMapping("/getAllForSelect")
    public Result<List<RoleResponse>> getAllRolesForSelect() {
        try {
            List<RoleResponse> roles = sysRoleService.getAllRolesForSelect();
            return Result.success(roles);
        } catch (Exception e) {
            log.error("获取角色列表失败", e);
            return Result.error("获取角色列表失败：" + e.getMessage());
        }
    }

    /**
     * 获取角色的权限列表
     */
    @GetMapping("/{roleId}/getPermissions")
    public Result<List<SysPermission>> getRolePermissions(@PathVariable @NotNull Long roleId) {
        log.info("管理员查询角色权限: roleId={}", roleId);
        try {
            // 检查角色是否存在
            RoleResponse role = sysRoleService.getRoleDetail(roleId);
            if (role == null) {
                return Result.error("角色不存在");
            }

            List<SysPermission> permissions = sysRoleService.getPermissionsByRoleId(roleId);
            return Result.success(permissions);
        } catch (Exception e) {
            log.error("查询角色权限失败", e);
            return Result.error("查询角色权限失败：" + e.getMessage());
        }
    }

    /**
     * 为角色分配权限
     */
    @PostMapping("/{roleId}/assignPermissions")
    public Result<Void> assignPermissionsToRole(@PathVariable @NotNull Long roleId,
                                                 @RequestBody @NotEmpty List<Long> permissionIds) {
        log.info("管理员为角色分配权限: roleId={}, permissionIds={}", roleId, permissionIds);
        try {
            // 获取当前登录用户的角色
            Long currentUserId = StpUtil.getLoginIdAsLong();
            List<Long> currentUserRoleIds = sysUserRoleService.getRoleIdsByUserId(currentUserId);

            // 检查是否尝试修改自己拥有的角色权限
            if (currentUserRoleIds.contains(roleId)) {
                return Result.error("管理员不能修改自己拥有的角色权限");
            }

            // 检查角色是否存在
            RoleResponse role = sysRoleService.getRoleDetail(roleId);
            if (role == null) {
                return Result.error("角色不存在");
            }

            // 验证权限是否存在
            List<SysPermission> availablePermissions = sysPermissionService.getAllPermissions();
            List<Long> availablePermissionIds = availablePermissions.stream()
                    .map(SysPermission::getId)
                    .toList();

            for (Long permissionId : permissionIds) {
                if (!availablePermissionIds.contains(permissionId)) {
                    return Result.error("权限ID " + permissionId + " 不存在");
                }
            }

            boolean success = sysRoleService.assignPermissions(roleId, permissionIds);
            if (success) {
                return Result.success("权限分配成功");
            } else {
                return Result.error("权限分配失败");
            }
        } catch (Exception e) {
            log.error("分配权限失败", e);
            return Result.error("分配权限失败：" + e.getMessage());
        }
    }

    /**
     * 移除角色的所有权限
     */
    @DeleteMapping("/{roleId}/removeAllPermissions")
    public Result<Void> removeAllPermissions(@PathVariable @NotNull Long roleId) {
        log.info("管理员移除角色所有权限: roleId={}", roleId);
        try {
            // 获取当前登录用户的角色
            Long currentUserId = StpUtil.getLoginIdAsLong();
            List<Long> currentUserRoleIds = sysUserRoleService.getRoleIdsByUserId(currentUserId);

            // 检查是否尝试修改自己拥有的角色权限
            if (currentUserRoleIds.contains(roleId)) {
                return Result.error("管理员不能修改自己拥有的角色权限");
            }

            // 检查角色是否存在
            RoleResponse role = sysRoleService.getRoleDetail(roleId);
            if (role == null) {
                return Result.error("角色不存在");
            }

            boolean success = sysRoleService.removeAllPermissions(roleId);
            if (success) {
                return Result.success("权限移除成功");
            } else {
                return Result.error("权限移除失败");
            }
        } catch (Exception e) {
            log.error("移除权限失败", e);
            return Result.error("移除权限失败：" + e.getMessage());
        }
    }

    /**
     * 获取所有权限列表（用于权限分配）
     */
    @GetMapping("/getAllPermissions")
    public Result<List<SysPermission>> getAllPermissions() {
        try {
            List<SysPermission> permissions = sysPermissionService.getAllPermissions();
            return Result.success(permissions);
        } catch (Exception e) {
            log.error("获取权限列表失败", e);
            return Result.error("获取权限列表失败：" + e.getMessage());
        }
    }
}
